package com.cskaoyan.javase.exception._1handle._3throws;

/**
 * @description: throws关键字
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * throws: 它有抛出的意思,它在方法的声明中使用,跟在方法形参的后面,方法体的前面
 *      它表示该方法抛出异常的可能性
 * 语法:
 *     [访问权限修饰符][其它修饰符] 返回值类型 方法名(形参列表) throws 异常列表{
 *
 *     }
 *
 * throws的使用:
 *      1.异常列表可以是一个异常,也可以是多个异常,之间用逗号隔开
 *          并且该关键字仅表示抛出异常的可能性,并不是真的直接抛出对象
 *          所以只需要写出异常的类名即可,无需加对象名
 *      2.对于运行时异常而言,一旦在方法中产生而没有做处理,默认就往上抛出
 *          所以对于运行时异常,无需使用throws关键字声明它的抛出(反正不处理它就要抛出)
 *          throws + 运行时异常没有任何意义
 *      3.throws关键字仅仅表示异常抛出的可能性,只是告诉方法的调用者"我可能有问题(会产生异常)",请小心使用方法
 *          它是否真的抛出异常,取决于方法体中的代码执行
 *      4.throws + 编译时异常就具有了含义,实际上对于编译时异常,它其中一种处理方式就是throws声明抛出
 *          一旦方法声明抛出编译时异常,就必须在调用该方法时,显式的处理该编译时异常
 *          处理的方式有两种:
 *              a.try...catch
 *              b.throws继续抛出
 *          一般情况下,不要在main方法中继续抛,最好处理它
 *
 *  思考:
 *      1.使用throws关键字在方法声明中抛出运行时异常,对方法的调用有影响吗?
 *          没有影响,实际上不应该使用throws关键字声明抛出运行时异常的可能性
 *
 *      2.使用throws关键字在方法声明中抛出编译时异常,对方法的调用有影响吗?
 *          有,必须显式处理它的方法调用,否者编译报错
 *
 *      3.既然throws关键字只是表示异常抛出的可能性,那么是否抛出异常,谁决定?
 *          方法的执行,决定了是否抛出异常
 * 注意事项:
 *     1. 运行时异常会自动向上抛出，不用我们手动throws,我们只需要手动throws编译时异常
 *     2.如果方法抛出一个编译时异常，可以在语法层面，强制要求方法调用者处理该异常
 *     3.异常列表可以是多个异常类，但是注意用逗号隔开
 *     4. 列表中出现的编译时异常如果有父子关系，那么编译器只会强制要求处理父类
 *           所以尽量抛出同级别的异常
 *
 *
 */
public class Demo implements Cloneable {
    public static void main(String[] args) {
        //testRuntime();
        try {
            testChecked();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        System.out.println("after");


        try {
            testException();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //抛出运行时异常
    public static void testRuntime() throws NullPointerException, ArrayIndexOutOfBoundsException, RuntimeException {
    }

    //声明抛出编译时异常
    public static void testChecked() throws CloneNotSupportedException {
        Demo d = new Demo();
        d.clone();
    }

    private static void testException() throws Exception, CloneNotSupportedException, RuntimeException {
    }


}
